package com.css.project.oa.cash.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.css.common.utils.SecurityUtils;
import com.css.common.utils.StringUtils;
import com.css.framework.security.LoginUser;
import com.css.framework.web.page.PageDomain;
import com.css.framework.web.page.TableSupport;
import com.css.project.oa.cash.domain.ProCash;
import com.css.project.oa.cash.mapper.ProCashMapper;
import com.css.project.system.service.ISysUserService;
import com.github.pagehelper.Page;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricTaskInstanceQuery;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.css.project.oa.cash.domain.ProCashAudit;
import com.css.project.oa.cash.service.IProCashAuditService;

/**
 * 现金报销单审核Service业务层处理
 * 
 * @author css
 * @date 2020-05-15
 */
@Service
public class ProCashAuditServiceImpl implements IProCashAuditService 
{
    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    public ProCashMapper proCashMapper;

    @Autowired
    private IdentityService identityService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;


    /**
     * 查询现金报销单审核列表
     * 
     * @param proCash 现金报销单审核
     * @return 现金报销单审核
     */
    @Override
    public List<ProCash> selectProCashAuditList(ProCash proCashAudit)
    {
        Page<ProCash> returnList = new Page<>();

        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();

        LoginUser cu = SecurityUtils.getLoginUser() ;
        // 根据当前人的ID查询
        //List<Task> todoList = taskService.createTaskQuery().processDefinitionKey("costSubmitProcess").taskAssignee(cu.getUser().getUserId().toString()).list();
        // 根据当前人未签收的任务
        TaskQuery taskQuery = taskService.createTaskQuery().processDefinitionKey("costSubmitProcess").or().taskCandidateUser(cu.getUser().getUserId().toString()).taskAssignee(cu.getUser().getUserId().toString()).endOr() ;
        if (StringUtils.isNotNull(proCashAudit.getExpenseName())){
            taskQuery.processVariableValueLike("expenseName","%"+proCashAudit.getExpenseName()+"%") ;
        }
        if (StringUtils.isNotNull(proCashAudit.getExpenseTime())){
            taskQuery.processVariableValueGreaterThanOrEqual("cashTimeEnd",proCashAudit.getExpenseTime()) ;
            taskQuery.processVariableValueLessThanOrEqual("cashTimeStart",proCashAudit.getExpenseTime()) ;
        }
        if (StringUtils.isNotNull(proCashAudit.getTotalAmountMin())){
            taskQuery.processVariableValueGreaterThanOrEqual("totalAmount",proCashAudit.getTotalAmountMin()) ;
        }
        if (StringUtils.isNotNull(proCashAudit.getTotalAmountMax())){
            taskQuery.processVariableValueLessThanOrEqual("totalAmount",proCashAudit.getTotalAmountMax()) ;
        }
        returnList.setTotal(taskQuery.count());
        List<Task> unsignedTasks =taskQuery.listPage((pageNum-1)*pageSize,pageSize);//分页查询
        for(Task task : unsignedTasks){//循环task，把业务model查询出来放进去
            String businessKey = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult().getBusinessKey() ;
            ProCash model = proCashMapper.selectProCashById(Long.parseLong(businessKey)) ;
            model.setExpenseName(userService.selectUserById(model.getBelongId()).getNickName() );
            model.setTaskName(task.getName());
            model.setTaskId(task.getId());
            returnList.add(model) ;
        }
        returnList.setPageNum(pageNum);
        returnList.setPageSize(pageSize);
        //return proCashAuditMapper.selectProCashAuditList(proCashAudit);
        return returnList ;
    }

    /**
     * 现金报销单审核
     * 
     * @param ProCash 现金报销单审核
     * @return 结果
     */
    @Override
    public int proCashAudit(ProCashAudit proCashAudit)
    {
        Map<String, Object> variables = new HashMap<>() ;
        variables.put("comment",proCashAudit.getComment()) ;
        String taskIds = proCashAudit.getTaskId() ;
        String[] taskIdList = taskIds.split(",") ;
        for(String taskId :taskIdList){
            Task task = taskService.createTaskQuery().processDefinitionKey("costSubmitProcess").taskId(taskId).singleResult() ;
            if(task.getTaskDefinitionKey().equals("deptManagerVerify")){
                variables.put("deptManagerResult",proCashAudit.getAuditOption()) ;
            }else if(task.getTaskDefinitionKey().equals("officeVerify")){
                variables.put("officeResult",proCashAudit.getAuditOption()) ;
            }
            if (StringUtils.isNotEmpty(proCashAudit.getComment())) {
                identityService.setAuthenticatedUserId(SecurityUtils.getLoginUser().getUser().getUserId().toString());
                taskService.addComment(taskId, task.getProcessInstanceId(), proCashAudit.getComment());
            }

            taskService.claim(taskId, SecurityUtils.getLoginUser().getUser().getUserId().toString());
            // 存储特殊的与任务关联的变量值
            taskService.setVariablesLocal(taskId, variables);//变量表里把taskId塞进去，不加的话taskId是空
            taskService.complete(taskId, variables);
        }
        return 1;
        //return proCashAuditMapper.updateProCashAudit(proCashAudit);
    }

    /**
     * 查询现金报销单审核已办列表
     *
     * @param proCash 现金报销单审核
     * @return 现金报销单审核
     */
    @Override
    public List<ProCash> selectProCashAuditDoneList(ProCash proCashAudit)
    {
        Page<ProCash> returnList = new Page<>();

        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();

        LoginUser cu = SecurityUtils.getLoginUser() ;
        // 根据当前人查询已办事项

        List<String> taskList = new ArrayList<>() ;taskList.add("部门经理审批") ;taskList.add("办公室审批") ;
        HistoricTaskInstanceQuery taskQuery = historyService.createHistoricTaskInstanceQuery()
                .processDefinitionKey("costSubmitProcess")
                .taskAssignee(cu.getUser().getUserId().toString())
                .taskNameIn(taskList)
                //.orderby
                .finished() ;

        if (StringUtils.isNotNull(proCashAudit.getExpenseName())){
            taskQuery.processVariableValueLike("expenseName","%"+proCashAudit.getExpenseName()+"%") ;
        }
        if (StringUtils.isNotNull(proCashAudit.getExpenseTime())){
            taskQuery.processVariableValueGreaterThanOrEqual("cashTimeEnd",proCashAudit.getExpenseTime()) ;
            taskQuery.processVariableValueLessThanOrEqual("cashTimeStart",proCashAudit.getExpenseTime()) ;
        }
        if (StringUtils.isNotNull(proCashAudit.getTotalAmountMin())){
            taskQuery.processVariableValueGreaterThanOrEqual("totalAmount",proCashAudit.getTotalAmountMin()) ;
        }
        if (StringUtils.isNotNull(proCashAudit.getTotalAmountMax())){
            taskQuery.processVariableValueLessThanOrEqual("totalAmount",proCashAudit.getTotalAmountMax()) ;
        }
        if(proCashAudit.getAuditOption()!=null){
            taskQuery.or().taskVariableValueEquals("deptManagerResult",proCashAudit.getAuditOption())
                    .taskVariableValueEquals("officeResult",proCashAudit.getAuditOption()).endOr() ;
        }
        returnList.setTotal(taskQuery.count());
        taskQuery = taskQuery.orderByHistoricTaskInstanceEndTime() .desc() ;
        List<HistoricTaskInstance> unsignedTasks =taskQuery.listPage((pageNum-1)*pageSize,pageSize);//分页查询
        for(HistoricTaskInstance task : unsignedTasks){//循环task，把业务model查询出来放进去
            String businessKey = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult().getBusinessKey() ;
            ProCash model = proCashMapper.selectProCashById(Long.parseLong(businessKey)) ;
            model.setExpenseName(userService.selectUserById(model.getBelongId()).getNickName() );
            model.setTaskName(task.getName());
            model.setTaskId(task.getId());
            model.setInstanceEndTime(task.getEndTime());
            List<HistoricVariableInstance> listVariable = historyService.createHistoricVariableInstanceQuery().taskId(task.getId()).list() ;
            for(HistoricVariableInstance v :listVariable){//这里做的不好了，以后的流程是否应该考虑所有变量名设置成一样的
                if(v.getVariableName().equals("deptManagerResult")){
                    model.setAuditOptionsStr(((Boolean)v.getValue())?"通过":"不通过");
                    break ;
                }
                if(v.getVariableName().equals("officeResult")){
                    model.setAuditOptionsStr(((Boolean)v.getValue())?"通过":"不通过");
                    break ;
                }
            }
            /*Map<String, Object> map = taskService.getVariablesLocal(task.getId());
            if(map.get("deptManagerResult") != null){
                model.setAuditOptions((Boolean) map.get("deptManagerResult"));
            }else if(map.get("officeResult") != null){
                model.setAuditOptions((Boolean) map.get("officeResult"));
            }
            List<Comment> comment = taskService.getTaskComments(task.getId(), "comment");
            if (!CollectionUtils.isEmpty(comment)) {
                model.setComment(comment.get(0).getFullMessage());
            }*/
            returnList.add(model) ;
        }
        returnList.setPageNum(pageNum);
        returnList.setPageSize(pageSize);
        //return proCashAuditMapper.selectProCashAuditList(proCashAudit);
        return returnList ;
    }
}
